package aliyun

import (
	"strconv"
	"time"

	"gitee.com/bjf-fhe/apicat/entry"
	"gitee.com/bjf-fhe/apicat/source"
	openapi "github.com/alibabacloud-go/darabonba-openapi/client"
	sls20201230 "github.com/alibabacloud-go/sls-20201230/client"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/sirupsen/logrus"
)

const TEN_MINUTES = 1000 * 60 * 10

type Reader struct {
	Url         string
	project     string
	logstore    string
	from        int64
	to          int64
	client      *sls20201230.Client
	chanEntries chan *entry.LogEntryResponse
}

func (r *Reader) Records() chan *entry.LogEntryResponse {
	return r.chanEntries
}

func (r *Reader) get() {
	var retry = 0
	for {
		res, err := r.client.GetLogs(&r.project, &r.logstore, &sls20201230.GetLogsRequest{
			From: tea.Int64(1670403589),
			To:   tea.Int64(1670493589),
		})
		if err == nil {
			if len(res.Body) > 0 {
				for _, item := range res.Body {
					logEntry := new(entry.LogEntry)
					if rmi, ok := item["request_method"]; ok {
						logEntry.Method = rmi.(string)
					}
					if rmi, ok := item["request_uri"]; ok {
						logEntry.Url = rmi.(string)
					}
					if rmi, ok := item["server_protocol"]; ok {
						logEntry.Protocol = rmi.(string)
					}
					if rmi, ok := item["status"]; ok {
						logEntry.StatusCode, _ = strconv.Atoi(rmi.(string))
					}
					if cip, ok := item["client_ip"]; ok {
						logEntry.Client = cip.(string)
					}
					if tm, ok := item["time"]; ok {
						logEntry.Created, _ = time.Parse(time.RFC3339, tm.(string))
					}
					r.chanEntries <- &entry.LogEntryResponse{
						Entry: logEntry,
					}
				}
			}

			r.from = r.to
			r.to += TEN_MINUTES
			time.Sleep(30 * time.Second)
			retry = 0
		} else {
			logrus.Errorln("aliyun log读取失败", err)
			retry++
			time.Sleep(time.Duration(retry*100) * time.Millisecond)
		}
	}
}

func createClient(ncfg *openapi.Config) (_result *sls20201230.Client, _err error) {

	// 访问的域名
	ncfg.Endpoint = tea.String(*ncfg.RegionId + ".log.aliyuncs.com")
	_result = &sls20201230.Client{}
	_result, _err = sls20201230.NewClient(ncfg)
	return _result, _err
}

func NewReader(dest string, ncfg *openapi.Config, project, logstore string) (source.Reader, error) {
	var h = &Reader{
		Url: dest,
	}
	var err error
	h.client, err = createClient(ncfg)
	h.project = project
	h.logstore = logstore
	h.to = time.Now().Unix()
	h.from = h.to - TEN_MINUTES
	h.chanEntries = make(chan *entry.LogEntryResponse)
	go h.get()
	return h, err
}
